package com.cloudinnov.logic.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cloudinnov.dao.AttachDao;
import com.cloudinnov.dao.ProductionLineEquipmentsDao;
import com.cloudinnov.dao.ProductionLinesDao;
import com.cloudinnov.logic.CapacityStatLogic;
import com.cloudinnov.logic.ProductionLinesLogic;
import com.cloudinnov.logic.RealTimeDataLogic;
import com.cloudinnov.model.Attach;
import com.cloudinnov.model.Companies;
import com.cloudinnov.model.EquipmentPoints;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.ProductionLineEquipments;
import com.cloudinnov.model.ProductionLines;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @author guochao
 * @date 2016年2月17日下午2:02:41
 * @email chaoguo@cloudinnov.com
 * @remark
 * @version
 */
@Service
public class ProductionLinesLogicImpl extends BaseLogicImpl<ProductionLines> implements ProductionLinesLogic {
	private static final Logger logger = LoggerFactory.getLogger(ProductionLinesLogicImpl.class);
	private static final String POINT_NAME = "point:";
	private static final String VALUE_NAME = ":value";
	private static final int REALTIME_TIME_OUT = 60;
	private static final String PRODUCT_TITLE = "product:state:";
	@SuppressWarnings("unused")
	private static final String PRODUCT_STARTTIME_TITLE = "product:startTime:";
	@SuppressWarnings("unused")
	private static final String PRODUCT_HEARTBEAR_TITLE = "product:heartbeat:";
	private static final String HISTORY_SPLITTER_LEVEL1 = ":";
	@SuppressWarnings("unused")
	private static final String HISTORY_SPLITTER_LEVEL2 = ";";
	@SuppressWarnings("unused")
	private static final String EQU_STATE_NORMAL_STRING = "3";
	private int digit = 5;
	@Autowired
	private ProductionLinesDao productionLinesDao;
	@Autowired
	private ProductionLineEquipmentsDao productLineEquDao;
	@Autowired
	private AttachDao attachDao;
	@Autowired
	private CapacityStatLogic capacityStatLogic;
	@Autowired
	private JedisPool jedisPool;
	@Autowired
	private RealTimeDataLogic realTimeDataLogic;

	public int save(ProductionLines productionLines) {
		productionLines.setCode(CodeUtil.prolineCode(digit));
		int returnCode = productionLinesDao.insert(productionLines);
		if (returnCode == CommonUtils.SUCCESS_NUM) {
			returnCode = productionLinesDao.insertInfo(productionLines);
		}
		return returnCode;
	}
	public int update(ProductionLines productionLines) {
		int returnCode = productionLinesDao.updateByCondition(productionLines);
		if (returnCode == CommonUtils.SUCCESS_NUM) {
			returnCode = productionLinesDao.updateInfoByCondition(productionLines);
		}
		return returnCode;
	}
	@Override
	public int selectProductionLineTotalByCustomerCode(String comCode) {
		return productionLinesDao.selectProductionLineTotalByCustomerCode(comCode);
	}
	@Override
	public int insertProductLineEquipment(ProductionLines productionLine) {
		int returnCode = productionLinesDao.insert(productionLine);
		if (returnCode == CommonUtils.SUCCESS_NUM) {
			returnCode = productionLinesDao.insertInfo(productionLine);
		}
		ProductionLineEquipments productionLineEquipments;
		if (returnCode == 1) {
			String[] equCodes = productionLine.getEquCodes().split(",");
			for (int i = 0; i < equCodes.length; i++) {
				productionLineEquipments = new ProductionLineEquipments();
				productionLineEquipments.setCustomerCode(productionLine.getCustomerCode());
				productionLineEquipments.setProductionLineCode(productionLine.getCode());
				productionLineEquipments.setEquipmentCode(equCodes[i]);
				productionLineEquipments.setOrderId(i);
				returnCode = productLineEquDao.insert(productionLineEquipments);
			}
		}
		return returnCode;
	}
	@Override
	public int updateProductLineEquipment(ProductionLines productionLine) {
		ProductionLineEquipments productionLineEquipments = new ProductionLineEquipments();
		String[] equCodes = productionLine.getEquCodes().split(",");
		if (equCodes == null) {
			return 0;
		}
		productionLineEquipments.setProductionLineCode(productionLine.getCode());
		int returnCode = productLineEquDao.deleteByCondition(productionLineEquipments);
		if (returnCode >= CommonUtils.SUCCESS_NUM) {
			for (int i = 0; i < equCodes.length; i++) {
				productionLineEquipments = new ProductionLineEquipments();
				productionLineEquipments.setCustomerCode(productionLine.getCustomerCode());
				productionLineEquipments.setProductionLineCode(productionLine.getCode());
				productionLineEquipments.setEquipmentCode(equCodes[i]);
				productionLineEquipments.setOrderId(i);
				returnCode = productLineEquDao.insert(productionLineEquipments);
			}
		}
		return returnCode;
	}
	@Override
	public List<Map<String, Object>> selectEquipmentByProLineCode(ProductionLineEquipments productionLineEqu) {
		return productLineEquDao.selectEquipmentByProLineCode(productionLineEqu);
	}
	@Override
	public List<ProductionLines> selectProductLineAll(int index, int size, ProductionLines productionLine) {
		return productionLinesDao.selectListByCondition(productionLine);
	}
	@Override
	public int selectProductionLineTotalByOemCode(Companies company) {
		return productionLinesDao.selectProductionLineTotalByOemCode(company);
	}
	@Override
	public List<Equipments> selectProlineEqusNotExists(ProductionLines productionLine) {
		return productionLinesDao.selectProlineEqusNotExists(productionLine);
	}
	@Override
	public int selectProlineStates(ProductionLines productionLine) {
		int returnCode = productionLinesDao.selectProlineStates(productionLine);
		if (returnCode >= CommonUtils.SUCCESS_NUM) {
			return 0;
		}
		return 1;
	}
	@Override
	public int saveOtherLanguage(ProductionLines productionLine) {
		return productionLinesDao.insertInfo(productionLine);
	}
	@Override
	public int updateOtherLanguage(ProductionLines productionLine) {
		return productionLinesDao.updateInfoByCondition(productionLine);
	}
	@Override
	public List<ProductionLines> selectProLineCodeNameByCustomerCode(String customerCodes, String language) {
		if (customerCodes == null) {
			return null;
		}
		String[] codes = customerCodes.split(",");
		ProductionLines productionLine = null;
		List<ProductionLines> list = new ArrayList<ProductionLines>();
		for (int i = 0; i < codes.length; i++) {
			productionLine = new ProductionLines();
			productionLine.setLanguage(language);
			productionLine.setCustomerCode(codes[i]);
			List<ProductionLines> result = productionLinesDao.selectProLineCodeNameByCustomerCode(productionLine);
			list.addAll(result);
		}
		return list;
	}
	@Override
	public ProductionLines select(ProductionLines productionLines) {
		ProductionLines productionLine = productionLinesDao.selectEntityByCondition(productionLines);
		if (productionLine != null) {
			// 查询产线下的设备列表
			List<Equipments> equList = productionLinesDao.selectEquipmentsByProductCode(productionLine);
			productionLine.setEquipments(equList);
		}
		return productionLine;
	}
	@Override
	public Page<ProductionLines> selectListPage(int index, int size, ProductionLines productionLines,
			boolean isOrderBy) {
		PageHelper.startPage(index, size);
		Page<ProductionLines> list = (Page<ProductionLines>) productionLinesDao.selectListByCondition(productionLines);
		for (int i = 0; i < list.size(); i++) {
			List<Equipments> equList = productionLinesDao.selectEquipmentsByProductCode(list.get(i));
			list.get(i).setEquipments(equList);
			List<String> equCodes = new ArrayList<String>();
			for (int j = 0; j < equList.size(); j++) {
				equCodes.add(equList.get(j).getCode());
			}
		}
		return (Page<ProductionLines>) list;
	}
	@Override
	public List<ProductionLines> selectList(ProductionLines productionLines, boolean isOrderBy) {
		List<ProductionLines> list = productionLinesDao.selectListByCondition(productionLines);
		for (int i = 0; i < list.size(); i++) {
			// 查询产线图片
			Attach attach = new Attach();
			attach.setObjectCode(list.get(i).getCode());
			attach.setType("productionLine");
			Attach images = attachDao.selectEntityByCondition(attach);
			if (images != null) {
				list.get(i).setImage(images.getUrl());
			}
			// 查询产线产能
			capacityStatLogic.selectCapacityByProductLine(list.get(i));
			List<Equipments> equList = productionLinesDao.selectEquipmentsByProductCode(list.get(i));
			list.get(i).setEquipments(equList);
			List<String> equCodes = new ArrayList<String>();
			for (int j = 0; j < equList.size(); j++) {
				equCodes.add(equList.get(j).getCode());
			}
			list.get(i).setEquipmentCodes(equCodes);
			List<EquipmentPoints> pointList = productionLinesDao.selectPointsByProductCode(list.get(i));
			list.get(i).setPoints(pointList);
			for (int k = 0; k < list.get(i).getPoints().size(); k++) {
				if (list.get(i).getPoints().get(k).getType().equals(CommonUtils.POINT_TYPE_MN)) {
					if (list.get(i).getPoints().get(k).getConfig().split("\\|").length > 4) {
						list.get(i).getPoints().get(k)
								.setUnit(list.get(i).getPoints().get(k).getConfig().split("\\|")[0]);
						list.get(i).getPoints().get(k)
								.setMin(list.get(i).getPoints().get(k).getConfig().split("\\|")[2]);
						list.get(i).getPoints().get(k)
								.setMax(list.get(i).getPoints().get(k).getConfig().split("\\|")[4]);
						list.get(i).getPoints().get(k).setConfig("");
					}
				} else if (list.get(i).getPoints().get(k).getType().equals(CommonUtils.POINT_TYPE_SZ)) {
					list.get(i).getPoints().get(k).setUnit("");
					list.get(i).getPoints().get(k).setMin(0);
					list.get(i).getPoints().get(k).setMax(1);
					list.get(i).getPoints().get(k).setConfig("");
				}
			}
		}
		return list;
	}
	@Override
	public List<ProductionLines> selectProLineInfoByCode(String customerCode, String language) {
		ProductionLines productionLine = new ProductionLines();
		productionLine.setCustomerCode(customerCode);
		productionLine.setLanguage(language);
		return productionLinesDao.selectProLineInfoByCode(productionLine);
	}
	@Override
	public List<ProductionLines> selectProLinesByCustomerCode(ProductionLines productionLine) {
		Jedis redis = null;
		List<ProductionLines> list = new ArrayList<ProductionLines>();
		try {
			redis = jedisPool.getResource();
			StringBuilder sb = null;
			if (productionLine.getCode() != null && !productionLine.getCode().equals("")) {
				ProductionLines proLineModel = productionLinesDao.selectEntityByCondition(productionLine);
				if (productionLine != null) {
					list.add(proLineModel);
				}
			} else {
				list = productionLinesDao.selectListByCondition(productionLine);
			}
			for (int i = 0; i < list.size(); i++) {
				List<Equipments> equList = productionLinesDao.selectEquipmentsByProductCode(list.get(i));
				for (Equipments equipment : equList) {
					EquipmentPoints point = new EquipmentPoints();
					point.setLanguage(productionLine.getLanguage());
					point.setEquipmentCode(equipment.getCode());
					List<EquipmentPoints> equipmentPoints = realTimeDataLogic.selectRealtimeDatasByEquipment(point);
					equipment.setPoints(equipmentPoints);
				}
				list.get(i).setEquipments(equList);
				List<String> equCodes = new ArrayList<String>();
				for (int j = 0; j < equList.size(); j++) {
					equCodes.add(equList.get(j).getCode());
				}
				list.get(i).setEquipmentCodes(equCodes);
				List<EquipmentPoints> pointList = productionLinesDao.selectPointsByProductCode(list.get(i));
				list.get(i).setPoints(pointList);
				// 查询产线产能
				if (pointList != null && pointList.size() > 0) {
					for (EquipmentPoints point : pointList) {
						if (point.getIsProductivity() != null && point.getIsProductivity() == CommonUtils.SUCCESS_NUM) {
							// 查询产线产能
							list.get(i).setProductivityCode(point.getCode());
							capacityStatLogic.selectCapacityByProductLine(list.get(i));
							break;
						}
					}
				}
				// 查询产线状态
				redis.select(CommonUtils.REDIS_STATE_VALUEDB);
				String state = redis.get(PRODUCT_TITLE + productionLine.getCode());
				if (state != null) {
					list.get(i).setCurrentState(CommonUtils.convertInteger(
							redis.get(PRODUCT_TITLE + productionLine.getCode()).split(HISTORY_SPLITTER_LEVEL1)[0]));
				}
				redis.select(CommonUtils.REDIS_POINT_VALUEDB);
				for (int k = 0; k < list.get(i).getPoints().size(); k++) {
					sb = new StringBuilder();
					sb.append(POINT_NAME).append(list.get(i).getPoints().get(k).getCode()).append(VALUE_NAME);
					String value = redis.lindex(sb.toString(), 0);
					if (value != null && ((System.currentTimeMillis() / 1000)
							- Integer.parseInt(value.split(",")[0])) < REALTIME_TIME_OUT) {
						list.get(i).getPoints().get(k)
								.setValue(Float.parseFloat((value.split(",")[1].replace(" ", ""))));
					}
					if (list.get(i).getPoints().get(k).getType().equals(CommonUtils.POINT_TYPE_MN)) {
						list.get(i).getPoints().get(k)
								.setUnit(list.get(i).getPoints().get(k).getConfig().split("\\|")[0]);
						String min = list.get(i).getPoints().get(k).getConfig().split("\\|")[2];
						String max = list.get(i).getPoints().get(k).getConfig().split("\\|")[4];
						list.get(i).getPoints().get(k).setMin(CommonUtils.convertLong(min));
						list.get(i).getPoints().get(k).setMax(CommonUtils.convertLong(max));
						list.get(i).getPoints().get(k).setConfig(null);
					} else if (list.get(i).getPoints().get(k).getType().equals(CommonUtils.POINT_TYPE_SZ)) {
						list.get(i).getPoints().get(k).setUnit("");
						list.get(i).getPoints().get(k).setMin(0);
						list.get(i).getPoints().get(k).setMax(1);
						list.get(i).getPoints().get(k).setConfig(null);
					}
				}
			}
		} catch (Exception e) {
			logger.error("获取产线下的点位和值\t", e);
		} finally {
			jedisPool.returnResource(redis);
		}
		return list;
	}
	@Override
	public List<ProductionLines> selectProLinesEquipmentByCustomerCode(ProductionLines productionLines) {
		List<ProductionLines> list = productionLinesDao.selectListByCondition(productionLines);
		for (int i = 0; i < list.size(); i++) {
			List<Equipments> equList = productionLinesDao.selectEquipmentsByProductCode(list.get(i));
			list.get(i).setEquipments(equList);
		}
		return list;
	}
	@Override
	public List<ProductionLines> selectProLineInfoByCode(ProductionLines productionLine) {
		List<ProductionLines> list = productionLinesDao.selectProLineInfoByCode(productionLine);
		for (ProductionLines line : list) {
			line.setEquipments(null);
			line.setPoints(null);
		}
		return list;
	}
}
